import { deleteFile, IFileItem, moveFile, readDir, watchDir } from '@/appUtils/fs'
import { dirname, resolve } from '@/appUtils/path'
import { FSWatcher } from 'chokidar'
import { ElMessage } from 'element-plus'
import debounce from 'lodash-es/debounce'
import { onMounted, reactive, watch, watchEffect } from 'vue'
import { IFileItemSortCondition, sortFileList } from './sortAndFilter'

export interface IFileExplorerProps {
    defaultPath?: string
    defaultSortConditions?: IFileItemSortCondition[]
    watch?: boolean
}
export const useCurrentFolder = (props: Required<IFileExplorerProps>) => {
    const currentFolder = reactive({
        // 是否为激活状态
        isActive: false,
        // 当前目录
        path: resolve(props.defaultPath || './'),
        // 正在输入的目录
        inputingPath: resolve(props.defaultPath || './'),
        // 当前目录下的文件
        files: [] as IFileItem[],
        // 在页面上展示的文件，筛选等过后要显示的
        showFiles: [] as IFileItem[],
        // 被选中的文件
        selectedFiles: [] as string[],
        // 是否监听目录变化
        watch: props.watch,
        // 排序条件
        sortConditions: props.defaultSortConditions
    })

    let dirWatcher: FSWatcher | null | undefined = null

    // 当前目录发生变化时显示到输入框内
    watchEffect(() => {
        currentFolder.inputingPath = resolve(currentFolder.path)
    })

    const closeDirWatcher = () => {
        if (!dirWatcher) return
        dirWatcher.close()
        dirWatcher = null
    }

    const openDirWatcher = () => {
        closeDirWatcher()
        dirWatcher = watchDir(currentFolder.path)?.on('all', () => {
            debounceReadFolderAndShow(currentFolder.path)
        })
    }

    // 当前目录或者watch属性变化时更新watcher
    watch(
        () => currentFolder.path,
        (newValue, oldValue) => {
            console.log(newValue)
            if (!dirWatcher || newValue === oldValue) return
            if (oldValue && dirWatcher) {
                closeDirWatcher()
            }
            openDirWatcher()
        }
    )
    watch(
        () => currentFolder.watch,
        (newValue) => {
            if (!newValue && dirWatcher) {
                closeDirWatcher()
            }
            if (newValue && !dirWatcher) {
                openDirWatcher()
            }
        },
        {
            immediate: true
        }
    )

    // 读取文件夹并展示在页面中
    const readFolderAndShow = async (path: string) => {
        const resolvedPath = resolve(path)
        currentFolder.path = resolvedPath
        // 读取文件夹获取结构数据
        const files = await readDir(resolvedPath)
        sortFileList(files, currentFolder.sortConditions)
        currentFolder.files = files
        currentFolder.showFiles = files
    }
    // 读取文件夹并展示在页面中，防抖
    const debounceReadFolderAndShow = debounce(readFolderAndShow, 100)

    // 更换排序条件，外部调用
    const handleSortConditionsChange = (conditions: IFileItemSortCondition[]) => {
        currentFolder.sortConditions = conditions
        readFolderAndShow(currentFolder.path)
    }

    // 选中文件，外部调用
    const highlightFile = async (filePath: string) => {
        console.log(filePath)
        const dir = dirname(filePath)
        if (dir !== currentFolder.path) {
            await readFolderAndShow(dir)
        }
        const index = currentFolder.files.findIndex((file) => file.path === filePath)
        if (index === -1) return
        const fileItem = currentFolder.files[index]
        selectSingleFile(fileItem)
        return index
    }

    // 处理rename
    const handleRename = async (oldPath?: string, newPath?: string) => {
        if (!oldPath || !newPath) return
        try {
            await moveFile(oldPath, newPath)
            readFolderAndShow(currentFolder.path)
        } catch {
            ElMessage.error('重命名失败')
        }
    }

    // 处理delete
    const handleDelete = async (path?: string) => {
        if (!path) return
        try {
            await deleteFile(path)
            readFolderAndShow(currentFolder.path)
        } catch {
            ElMessage.error('删除失败')
        }
    }

    // 跳转到输入的目录
    const goTo = async () => {
        const inputingPath = currentFolder.inputingPath
        const path = resolve(inputingPath)
        readFolderAndShow(path)
    }

    // 上一级目录
    const goUp = () => {
        currentFolder.path = resolve(currentFolder.path, '..')
        readFolderAndShow(currentFolder.path)
    }

    // 选中单个文件
    const selectSingleFile = (file: IFileItem) => {
        currentFolder.selectedFiles = [file.name]
    }

    // 双击，打开文件或文件夹
    const openFileOrDir = (file: IFileItem) => {
        if (file.isDir) {
            // 打开文件夹
            readFolderAndShow(file.path)
        } else {
            // 打开文件
            // openFile(file.path)
        }
    }

    // 一开始要显示
    onMounted(() => {
        readFolderAndShow(currentFolder.path)
    })

    return {
        currentFolder,
        openFileOrDir,
        selectSingleFile,
        goUp,
        goTo,
        handleRename,
        handleDelete,
        highlightFile,
        readFolderAndShow,
        debounceReadFolderAndShow,
        handleSortConditionsChange
    }
}
